home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / plane / _range_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  9.4 KB  |  405 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _range_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. #include <LEDA/impl/range_tree.h>
  17.  
  18.  
  19. // Let's start with some simple member functions of class rt_elem
  20.  
  21. // the 2-dimensional constructor
  22. //
  23. rt_elem::rt_elem(GenPtr k0, GenPtr k1, GenPtr i) {
  24.   rt_keys=new GenPtr[2];
  25.   rt_keys[0]=k0; rt_keys[1]=k1;
  26.   rt_inf=i;
  27. }
  28.  
  29. // the 3-dimensional constructor
  30. //
  31. rt_elem::rt_elem(GenPtr k0, GenPtr k1, GenPtr k2, GenPtr i) {
  32.   rt_keys=new GenPtr[3];
  33.   rt_keys[0]=k0; rt_keys[1]=k1; rt_keys[2]=k2;
  34.   rt_inf=i;
  35. }
  36.  
  37. // the d-dimensional constructor
  38. //
  39. rt_elem::rt_elem(int dim, GenPtr* k, GenPtr i) {
  40.   rt_keys=new GenPtr[dim];
  41.   for( int d=0; d<dim; d++ )
  42.     rt_keys[d]=k[d];
  43.   rt_inf=i;
  44. }
  45.  
  46.  
  47.  
  48. // And here are the member functions of class range_tree
  49.  
  50. // insert new_elem into the primary tree and update its secondary 
  51. // structures if lev<dim-1
  52. //
  53. void range_tree::rt_insert( rt_item new_elem )
  54. {
  55.  
  56. #ifdef DEBUG
  57.   newline;
  58.   for( int auxl=0; auxl<lev; auxl++ ) cout << "\t";
  59.   cout << "insert " << (int) new_elem->inf() << ":   "; cout.flush();
  60. #endif
  61.  
  62.   if( lev<dim-1 ) {            // take care of secondary structures
  63.  
  64.     base_tree_item p, new_leaf;
  65.     range_tree* sec;
  66.  
  67.     // insert the new element into the primary tree 
  68.     //
  69.     aux.clear();
  70.     new_leaf = base_tree::insert( new_elem, new_range_tree(dim,lev+1), 
  71.                               new_range_tree(dim,lev+1) );
  72.   
  73.     // now we insert the new element into all secondary structures of 
  74.     // nodes on the path from the root to the new leaf with a non-empty
  75.     // secondary structure (remember that these nodes are not in aux)
  76.     //
  77.     p = root();
  78.     while( p ) {
  79.       sec = (range_tree*) inf(p);
  80.       if( sec->size() )
  81.         sec->rt_insert(new_elem);
  82.       if( cmp(new_elem,key(p))<=0 )
  83.         p = l_child(p);
  84.       else
  85.         p = r_child(p);
  86.     }
  87.  
  88.     // and into the (empty) secondary structure of the new leaf
  89.     //
  90.     ((range_tree*) inf(new_leaf))->rt_insert(new_elem);
  91.  
  92.     // for all nodes appended to aux by the function propagate_change(), 
  93.     // we rebuild the secondary structure from scratch
  94.     //
  95.     rt_item* elem_array = new rt_item[size()];        // array of elements
  96.     int elem_no;                    // number of elements
  97.  
  98.     forall( p, aux ) {
  99.       elem_no = elements_in_subtree(elem_array, p);
  100.       ((range_tree*) inf(p))->build_tree(elem_array, 0, elem_no-1);
  101.     }
  102.   
  103.     delete elem_array;
  104.   }
  105.   else
  106.     // for lev==dim-1 the range tree is just an ordinary search tree
  107.     //
  108.     base_tree::insert( new_elem, 0, 0 );
  109. }
  110.  
  111.  
  112.  
  113.  
  114.  
  115. // recursively build a range tree for the elements 
  116. // elem_array[lidx],...,elem_array[ridx]
  117. // if p==0 we build the tree on this level and the secondary structure of the
  118. // root, otherwise we just build the secondary structure of p
  119. //
  120. void range_tree::build_tree( rt_item* elem_array, int lidx, int ridx, 
  121.                  base_tree_item p )
  122. {
  123.  
  124. #ifdef DEBUG
  125.   newline;
  126.   for( int gg=0; gg<lev; gg++ )
  127.     cout << "\t";
  128.   cout << "build_tree " << p << ":   ";
  129.   cout.flush();
  130. #endif
  131.  
  132.   int i;
  133.  
  134.   // the last level of the range tree is just a binary search tree
  135.   //
  136.   if( lev==dim-1 ) {
  137.     for( i=lidx; i<=ridx; i++ ) {
  138.  
  139. #ifdef DEBUG
  140.       newline;
  141.       for( int gg=0; gg<lev; gg++ )
  142.         cout << "\t";
  143.       cout << "insert " << (int) elem_array[i]->inf() << ":   ";
  144.       cout.flush();
  145. #endif
  146.  
  147.       base_tree::insert( elem_array[i], 0, 0 );
  148.     }
  149.     return;
  150.   }
  151.  
  152.   // we are entering this level for the first time, therefor we have
  153.   // to insert all elements and sort them according to the new level
  154.   //
  155.   if( !p ) {
  156.     for( i=lidx; i<=ridx; i++ ) {
  157.  
  158. #ifdef DEBUG
  159.       newline;
  160.       for( int gg=0; gg<lev; gg++ )
  161.         cout << "\t";
  162.       cout << "insert " << (int) elem_array[i]->inf() << ":   ";
  163.       cout.flush();
  164. #endif
  165.  
  166.       base_tree::insert( elem_array[i], new_range_tree(dim,lev+1), 
  167.                                         new_range_tree(dim,lev+1) );
  168.     }
  169.     p = root();
  170.     elem_array = new rt_item[ridx-lidx+1];
  171.     lidx = 0;
  172.     ridx = elements_in_subtree(elem_array,p)-1;    /* get sorted array */
  173.   }
  174.  
  175.   // build the secondary structure
  176.   //
  177.   ((range_tree*) inf(p))->build_tree(elem_array, lidx, ridx);
  178.  
  179.   // if p is an inner node, we recursively build the secondary structures
  180.   // of its children
  181.   //
  182.   if (is_inner(p)) {
  183.     int l=lidx, r=ridx, med=(l+r)/2, c=cmp(elem_array[med],key(p));
  184.  
  185.     // "split" the array at key(p)
  186.     //
  187.     while( c ) {
  188.       if( c>0 )
  189.     r = med-1;
  190.       else
  191.     l = med+1;
  192.       med = (l+r)/2;
  193.       c = cmp(elem_array[med], key(p));
  194.     }
  195.  
  196.     if (r_child(p))
  197.       build_tree(elem_array, med + 1, ridx, r_child(p));
  198.     if (l_child(p))
  199.       build_tree(elem_array, lidx, med, l_child(p));
  200.   }
  201.  
  202.   // free the memory of the array elem_array, if we are done
  203.   //
  204.   if( p==root() )
  205.     delete elem_array;
  206. }
  207.  
  208.  
  209.  
  210. // compute a sorted array (according to the actual level) of all 
  211. // elements in the subtree rooted at subroot and return their number
  212. //
  213. int range_tree::elements_in_subtree( rt_item* elem_array, 
  214.                      base_tree_item subroot )
  215. {
  216.   int elem_no=0;
  217.   base_tree_item p=subroot, q=subroot;
  218.  
  219.   while( is_inner(p) )            // find leftmost leaf
  220.     p = l_child(p);
  221.   while( is_inner(q) )            // find rightmost leaf
  222.     q = r_child(q);
  223.  
  224.   while( p!=q ) {            // collect all elements inbetween
  225.     elem_array[elem_no++] = rt_item(key(p));
  226.     p = succ(p);
  227.   }
  228.   elem_array[elem_no++] = rt_item(key(q));
  229.  
  230.   return elem_no;            // return the number of elements
  231. }
  232.  
  233.  
  234.  
  235.  
  236. // return a list of all elements in the tree whose key is between
  237. // left and right on each level
  238. //
  239. void range_tree::rt_query( rt_item& left, rt_item& right, 
  240.                list<rt_item>& res )
  241. {
  242.   if( size()>0 ) {            // avoid special case
  243.     base_tree_item p, q;
  244.  
  245.     if( lev<dim-1 ) {            // we have to perform recursive quieries
  246.  
  247.       // find the last node common to both search paths
  248.       //
  249.       p = root();
  250.       while( is_inner(p) ) {
  251.     if( cmp(right,key(p))<=0 )
  252.       p = l_child(p);
  253.     else if( cmp(left,key(p))>0 )
  254.       p = r_child(p);
  255.     else
  256.       break;
  257.       }
  258.  
  259.       if( is_inner(p) ) {
  260.  
  261.         // traverse the left subpath
  262.     //
  263.     q = l_child(p);
  264.     while( is_inner(q) ) {
  265.       if( cmp(left,key(q))<=0 ) {
  266.         if( r_child(q) )
  267.           // recursively query all nodes right to the subpath
  268.           //
  269.           ((range_tree*) inf(r_child(q)))->rt_query(left,right,res);
  270.         q = l_child(q);
  271.       }
  272.       else
  273.         q = r_child(q);
  274.     }
  275.     if( cmp(left,key(q))<=0 && cmp(right,key(q))>=0 )
  276.       ((range_tree*) inf(q))->rt_query(left,right,res);
  277.  
  278.         // traverse the right subpath
  279.     //
  280.     q = r_child(p);
  281.     while( is_inner(q) ) {
  282.       if( cmp(right,key(q))>0 ) {
  283.         if( l_child(q) )
  284.           // recursively query all nodes left to the subpath
  285.           //
  286.           ((range_tree*) inf(l_child(q)))->rt_query(left,right,res);
  287.         q = r_child(q);
  288.       }
  289.       else
  290.         q = l_child(q);
  291.     }
  292.     if( cmp(left,key(q))<=0 && cmp(right,key(q))>=0 )
  293.       ((range_tree*) inf(q))->rt_query(left,right,res);
  294.       }
  295.       else {
  296.         // we only have to look at one leaf
  297.     //
  298.     if( cmp(left,key(p))<=0 && cmp(right,key(p))>=0 )
  299.       ((range_tree*) inf(p))->rt_query(left,right,res);
  300.       }
  301.     }
  302.     else {
  303.       // append all elements between left and right on level dim-1
  304.       // to the res
  305.       //
  306.       p = locate_succ( left );
  307.       while( p && cmp(key(p),right)<=0 ) {
  308.         res.append( rt_item(key(p)) );
  309.         p = succ(p);
  310.       }
  311.     }
  312.   }
  313. }
  314.  
  315.  
  316.  
  317. // delete elem in the primary tree and update its secondary 
  318. // structures if lev<dim-1
  319. //
  320. void range_tree::rt_del( rt_item elem )
  321. {
  322.   if( lev<dim-1 ) {            // take care of secondary structures
  323.     base_tree_item p;
  324.  
  325.     // delete elem in all secondary structures on the search path to elem
  326.     //
  327.     p = root();
  328.     while( is_inner(p) ) {
  329.       ((range_tree*) inf(p))->rt_del(elem);
  330.       if( cmp(elem,key(p))<=0 )
  331.         p = l_child(p);
  332.       else
  333.         p = r_child(p);
  334.     };
  335.  
  336.     // and in the primary tree
  337.     //
  338.     aux.clear();
  339.     base_tree::del_item(p);
  340.  
  341.     // for all nodes appended to aux by the function propagate_change(), 
  342.     // we rebuild the secondary structure from scratch
  343.     //
  344.     rt_item* elem_array = new rt_item[size()];        // array of elements
  345.     int elem_no;                    // number of elements
  346.  
  347.     forall( p, aux ) {
  348.       elem_no = elements_in_subtree(elem_array, p);
  349.       ((range_tree*) inf(p))->build_tree(elem_array, 0, elem_no-1);
  350.     }
  351.   
  352.     delete elem_array;
  353.   }
  354.   else
  355.     // for lev==dim-1 the range tree is just an ordinary search tree
  356.     //
  357.     base_tree::del(elem);
  358. }
  359.  
  360.  
  361.  
  362. // return a list of all elements in the tree
  363. //
  364. list<rt_item> range_tree::all_items()
  365. {
  366.   list<rt_item> res;
  367.  
  368.   if( !empty() ) {
  369.     base_tree_item p=base_tree::min(),
  370.                    q=base_tree::max();
  371.     res.append( (rt_item) key(p) );
  372.     while( p!=q ) {
  373.       p = cyclic_succ(p);
  374.       res.append( (rt_item) key(p) );
  375.     }
  376.   }
  377.   return res;
  378. }
  379.  
  380.  
  381.  
  382. // compute minimum element on a given level
  383. //
  384. rt_item range_tree::rt_min( int d ) 
  385. {
  386.   if( empty() ) return 0;
  387.   if( lev<d )                    // proceed to next level
  388.     return ((range_tree*) inf(root()))->rt_min(d);
  389.   else 
  390.     return( (rt_item) key(base_tree::min()) );
  391. }
  392.  
  393.  
  394.  
  395. // compute maximum element on a given level
  396. //
  397. rt_item range_tree::rt_max( int d ) {
  398.   if( empty() ) return 0;
  399.   if( lev<d )                    // proceed to next level
  400.     return ((range_tree*) inf(root()))->rt_max(d);
  401.   else 
  402.     return( (rt_item) key(base_tree::max()) );
  403. }
  404.